import cgi
import os
from google.appengine.ext.webapp import template
from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
import urllib2
import requests
import simplejson
import json
import jsontemplate
import config
import modify

url = 'http://us.api.invisiblehand.co.uk/v1/products'

modify.read_input('indext.txt')
modify.read_input('index2t.txt')

modify.read_to_template1(config.ts_1)
modify.read_to_template2(config.ts_2)



# function to render template for state where data and budget are present
def rendert2():
	resultString=config.t2.expand(config.data)
	color = modify.budgetWarningLevel(config.budget, config.selectedItems, config.data)
	resultString = resultString.replace('!color!', str(color))
	resultString = resultString.replace('!budget!', str(config.budget))
	recDic = modify.recommend(config.budget, config.selectedItems, config.data)
	for key,value in recDic.items():
		if key not in config.selectedItems:
			recDic[key] = "Recommended Price: $" + str(recDic[key])
	for key,value in recDic.items():
		tempString='!' + key + '!'
		resultString=resultString.replace(tempString,value)
	resultString = resultString.replace('!totalPrice!', str(config.totalPrice))
	resultString = resultString.replace('!search!', '')
	return resultString

# function to render template where only data is present(no budget)
def rendert():
	resultString = config.t1.expand(config.data)
	resultString = resultString.replace('!budget!', '')
	resultString = resultString.replace('!totalPrice!', str(config.totalPrice))
	resultString = resultString.replace('!search!', '')
	selecDic = modify.selections(config.selectedItems, config.data)
	for key,value in selecDic.items():
		tempString = '!' + key + '!'
		resultString=resultString.replace(tempString,value)
	return resultString
  
# function to render more info
def renderInfo(searchterm,itmId, itmPrice):
	#need to get more info on selected item
	#need to render with appengine template or with jsont
	for x in config.data:
		if x['searchterm']==searchterm:
			for y in x['results']:
				if y['id'] == itmId:
					if y['best_page']['in_stock'] =='true':
						stock = "Currently In Stock"
					else:
						stock ="Out of Stock"
					template_values = {'id':itmId,'budget': config.budget, 'title': y['title'], 'price':itmPrice, 'image': y['best_page']['image_url'], 'retailer':y['best_page']['retailer_name'], 'description': y['best_page']['description'], 'stock': stock, 'brand':y['brands'], 'url':y['best_page']['original_url'], 'category':y['categories']}
					path = os.path.join(os.path.dirname(__file__),'info.html')
					return template.render(path,template_values)
	return 'Product not Found'

# function which chooses which data template to render
def rendData():
	if (config.budget == ''):
       resultString = rendert()
    else:
       resultString = rendert2()
	return resultString
  
# select function
# used for consistently maintained button functionality across different displays(states)
def select(searchterm, but):
	if but =='Select':  
		#get selection
		selectedItm = self.request.get(searchterm)
		selectedItm = selectedItm.split('-')
		itmId = selectedItm[0]
  
		if len(selectedItm)<2:
			itmPrice =0.00
		else:
			itmPrice = selectedItm[1]
			
		#add the selected product to selectedItems dictionary
		if modify.search_items(searchterm):
			modify.add_id(itmId, searchterm)
			modify.add_price(itmPrice, searchterm)
			modify.add_total(itmPrice)                      
		else:
			#remove old item
			lastPrice = modify.get_price(searchterm)
			modify.sub_total(lastPrice)
			#add new item
			modify.add_id(itmId, searchterm)
			modify.add_price(itmPrice, searchterm)
			modify.add_total(itmPrice)
			
		#get rendered resulting output
		resultString = rendData()	
    elif but =='Reset':
		if modify.search_items(searchterm) is False:
			lastPrice = modify.get_price(searchterm)
			modify.sub_total(lastPrice)
			modify.removeSelect(searchterm)
		resultString = rendData()
	elif but == 'More Info':
		resultString = renderInfo(searchterm, itmId, itmPrice)
	elif but == 'Return to Results':
		resultString = rendData()
	else:
		print "Error: Search selection did not match any option in function select(but)"
		print "Selected button value is " + str(but)
		resultString = "Error: Button did not match any valid values"
	return resultString

	
	
	
# main page appears on load
class MainPage(webapp.RequestHandler):
  def get(self):
	# render the initial page
    template_values={'budget': config.budget}
    path = os.path.join(os.path.dirname(__file__),'index.html')
    self.response.out.write(template.render(path,template_values))
    
# Display function for budget value submit
# Alternates with BudgetReload
# Reads in budget and switches view to index2.html if no data and index2t.txt if data
class BudgetSubmit(webapp.RequestHandler):
  def post(self):
	# read in budget
    formBudget=self.request.get('budget')
    modify.update_budget(formBudget)
	
	# clean initial budget(checks validity and removes strings)
    intBudget = config.budget
    if (config.budget != ''):
		if intBudget[0] == '$':
			config.budget = config.budget[1:]
			if config.budget.isnumeric():
				config.budget = float(config.budget)
			else:
				modify.update_budget('')
		elif config.budget[0] != '$':
			if config.budget.isnumeric():
				config.budget = float(config.budget)
			else:
				modify.update_budget('')

    # render the page(choose page based off of presence of budget and data)
    if(len(config.data) == 0):
		template_values={'budget': config.budget}
		if (config.budget == ''):
			path = os.path.join(os.path.dirname(__file__),'index.html')
		else:
			path = os.path.join(os.path.dirname(__file__),'index2.html')
		resultString = template.render(path,template_values)
    else:
		resultString = rendData()
	
	# render the page(display output)
    self.response.out.write(resultString)

	
# Display function for budget reset(budget value previously stored, reset value)
# Alternates with BudgetSubmit
# Deletes previous budget and switches view to index.html if no data and indext.txt if data
class BudgetReload(webapp.RequestHandler):
  def post(self):
    modify.update_budget('')

	# rendering: choose between two possible state resulting from a budget reset action
    if(len(config.data) == 0):
		template_values={'budget': config.budget}
		path = os.path.join(os.path.dirname(__file__),'index.html')
		resultString = template.render(path,template_values)
    else:
		resultString = rendert()
	
	#render the page(display output)
    self.response.out.write(resultString)
 
	 
# Return Action
# used by Info.html page to return to the main results display
# has buttons: "Select" and "Return to Results"	
class Return(webapp.RequestHandler):
	def post(self):
		form = cgi.FieldStorage()
		searchterm = self.request.get('search')
		
		# perform actions consistent with possible result buttons and return resulting display
		resultString = select(searchterm, str(self.request.get('Bsubmit')))
		
		# render the page(display output)
		self.response.out.write(resultString)
	 
	 
# Function when values are selected
# Reads in data on what selected item is updates total price and recommended prices
# Display is either indext.txt if no budget or index2t.txt if budget     
class ItemSelect(webapp.RequestHandler):
	def post(self):
		form = cgi.FieldStorage()
		searchterm = self.request.get('search')
		
		# checks if empty selection
		if len(self.request.get(searchterm)) != 0:
			# run valid select
			resultString = select(searchterm, str(self.request.get('Bsubmit')))
		else:
			# checks if Reset with no dropdown selection
			if str(self.request.get('Bsubmit'))=='Reset':
				lastPrice = modify.get_price(searchterm)
				if modify.search_items(searchterm) is False:
					modify.sub_total(lastPrice)
					modify.removeSelect(searchterm)
				resultString = rendData()
			# checks if More Info with no selection(previous and in drop down)
			elif self.request.get('Bsubmit')=='More Info':
				if searchterm in config.selectedItems:
					resultString = renderInfo(searchterm, config.selectedItems[searchterm]['id'], config.selectedItems[searchterm]['price'])
				else:
					resultString = rendData()
			# checks for select with no selection
			else: 
				resultString = rendData()
				
		# render the page(display output)
		self.response.out.write(resultString)
     
      
# Search function(newSearch and addItem)
# Reads in searchterms and type of search, performs search, switches view to either indext.txt if no budget and index2t.txt if budget
class SearchController(webapp.RequestHandler):
	def get(self):
		form = cgi.FieldStorage()
		formSearch=form.getvalue('search')
		modify.update_search(formSearch)

		if str(config.search) != "None":
			searchterm = {'app_key':config.app_key,'app_id':config.app_id,'order':"asc",'query':config.search }
			r=requests.get(url,params=searchterm)
      
			tempdict = r.json()
			tempdict['searchterm'] = config.search

			if self.request.get('search_type')=='newSrch': 
				modify.reset_total()  
				modify.clear_selected()     
				for x in range (0,len(config.data)):
					modify.clear_data()
				modify.add_data(tempdict)
			elif self.request.get('search_type')=='addItm':
				modify.add_data(tempdict)
		elif (self.request.get('search_type')=='newSrch') & (str(config.search) == 'None'): 
			modify.reset_total() 
			modify.clear_selected() 
			modify.update_budget('')
			for x in range (0,len(config.data)):
				modify.clear_data()
			
	template_values= {'budget': config.budget}
    if ((len(config.data) == 0) & (config.budget == '')):
      path = os.path.join(os.path.dirname(__file__),'index.html')
      resultString = template.render(path,template_values)
    elif ((len(config.data) == 0) & (config.budget != '')):
      path = os.path.join(os.path.dirname(__file__),'index2.html')
      resultString = template.render(path,template_values)
    else:
      resultString = rendData()
	
	# render the page(display output)
	self.response.out.write(resultString)
    


# create this global variable that represents the application and specifies which class
# should handle each page in the site
app = webapp.WSGIApplication(
                                        # MainPage handles the home page load
                                     [('/', MainPage),
                                      ('/onSearch', SearchController), 
                                      ('/onSubmit', BudgetSubmit),
                                      ('/onReset', BudgetReload),
                                      ('/onSelect', ItemSelect),
                                      ('/onReturn', Return)],
                                     debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()
